package com.waterworld.watch.chat.adapter;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.drawable.AnimationDrawable;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.waterworld.watch.R;
import com.waterworld.watch.common.application.MyApplication;
import com.waterworld.watch.common.bean.UserInfoBean;
import com.waterworld.watch.common.customview.CircleImageView;
import com.waterworld.watch.common.db.DbController;
import com.waterworld.watch.common.db.Message;
import com.waterworld.watch.common.net.UrlContants;
import com.waterworld.watch.common.util.PhotoUtils;
import com.waterworld.watch.common.util.TimeUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;


import static com.waterworld.watch.common.util.TimeUtils.getHourAndMinute;
import static com.waterworld.watch.common.util.TimeUtils.getNormalTime;

/**
 * Created by nhuan on 2019/3/20.
 */

public class ChatMsgAdapter extends RecyclerView.Adapter<ChatMsgAdapter.MyHolder>{

    public static final int MSG_TYPE_TEXT = 1;
    public static final int MSG_TYPE_AUDIO = 2;
    public static final int MSG_TYPE_PICTURE = 3;

    public static final int MSG_STATE_UNREAD = 0;
    public static final int MSG_STATE_READ = 1;
    public static final int MSG_STATE_DOWNLOADING = 2;
    public static final int MSG_STATE_DOWNLOAD_FAIL = 3;
    public static final int MSG_STATE_PLAYING = 4;

    private static final int VIEW_TYPE_SELF = 0;
    private static final int VIEW_TYPE_OTHERS = 1;

    private static final int DOWNLOAD_SUCCESS = 0x01;

    private Context mContext;
    private List<Message> mList;
    private MediaPlayer mediaPlayer;
    //当前播放音频位置
    private int currentPlayPosition = RecyclerView.NO_POSITION;
    //当前播放动画
    private AnimationDrawable playAnimation;
    //数据库操作
    private DbController dbController = DbController.getInstance(MyApplication.getContext());

    public ChatMsgAdapter(Context context,List<Message> list) {
        mContext = context;
        mList = list;
        mediaPlayer = new MediaPlayer();
    }

    @NonNull
    @Override
    public MyHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        switch (i) {
            case VIEW_TYPE_SELF:
                return new MyHolder(LayoutInflater.from(mContext).inflate(R.layout.chat_msg_item_right,viewGroup,false));
            case VIEW_TYPE_OTHERS:
            default:
                return new MyHolder(LayoutInflater.from(mContext).inflate(R.layout.chat_msg_item_left,viewGroup,false));
        }
    }

    @Override
    public void onBindViewHolder(@NonNull MyHolder myHolder, int i) {
        if (i>0) {
            Message lastMsg = mList.get(i-1);
            if (Integer.parseInt(TimeUtils.getDatePoor(lastMsg.getCreateTime(),mList.get(i).getCreateTime())) > 24) {
                myHolder.tv_msg_time.setVisibility(View.VISIBLE);
                myHolder.tv_msg_time.setText(getNormalTime(mList.get(i).getCreateTime()));
            } else if (Integer.parseInt(TimeUtils.getDatePoor(lastMsg.getCreateTime(),mList.get(i).getCreateTime())) > 1) {
                myHolder.tv_msg_time.setVisibility(View.VISIBLE);
                myHolder.tv_msg_time.setText(getHourAndMinute(mList.get(i).getCreateTime()));
            } else {
                myHolder.tv_msg_time.setVisibility(View.VISIBLE);
                myHolder.tv_msg_time.setVisibility(View.GONE);
            }
        } else {
            myHolder.tv_msg_time.setVisibility(View.VISIBLE);
            myHolder.tv_msg_time.setText(getNormalTime(mList.get(i).getCreateTime()));
        }
        myHolder.tv_name.setText(mList.get(i).getName());
        if (mList.get(i).getHead() == null) {
            Glide.with(mContext).load(R.drawable.headimage_default).into(myHolder.iv_headimage);
        } else {
            if (mList.get(i).getHead().startsWith("sys")) {
                if (mList.get(i).getSenderType() == 1) {
                    Glide.with(mContext).load(PhotoUtils.getResource(mList.get(i).getHead().substring(0, 13))).into(myHolder.iv_headimage);
                } else if (mList.get(i).getSenderType() == 2) {
                    Glide.with(mContext).load(PhotoUtils.getResource(mList.get(i).getHead().substring(0, 12))).into(myHolder.iv_headimage);
                }
            } else {
                Glide.with(mContext).load(UrlContants.FILE_URL + "resources/watch/" + mList.get(i).getHead()).into(myHolder.iv_headimage);
            }
        }
        ViewGroup.LayoutParams layoutParams = myHolder.fl_chat_msg.getLayoutParams();
        switch (mList.get(i).getMsgType()) {
            case MSG_TYPE_TEXT:
                myHolder.ll_audio_msg.setVisibility(View.GONE);
                myHolder.tv_text_msg.setVisibility(View.VISIBLE);
                myHolder.tv_text_msg.setText(mList.get(i).getMsgContent());
                layoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
                myHolder.fl_chat_msg.setLayoutParams(layoutParams);
                myHolder.iv_unread.setVisibility(View.GONE);
                mList.get(i).setState(MSG_STATE_READ);
                dbController.insertOrReplace(mList.get(i));
                break;
            case MSG_TYPE_AUDIO:
                myHolder.ll_audio_msg.setVisibility(View.VISIBLE);
                myHolder.tv_text_msg.setVisibility(View.GONE);
                myHolder.tv_duration.setText(mList.get(i).getMsgLength()+mContext.getString(R.string.chat_msg_second));
                layoutParams.width = (int)( mContext.getResources().getDimension(R.dimen.size_58) + mList.get(i).getMsgLength() * mContext.getResources().getDimension(R.dimen.size_16));
                myHolder.fl_chat_msg.setLayoutParams(layoutParams);
                switch (mList.get(i).getState()) {
                    case MSG_STATE_UNREAD:
                        myHolder.iv_unread.setVisibility(View.VISIBLE);
                        myHolder.iv_download_fail.setVisibility(View.GONE);
                        myHolder.iv_downloading.setVisibility(View.GONE);
                        myHolder.playAnim.stop();
                        myHolder.playAnim.selectDrawable(0);
                        break;
                    case MSG_STATE_READ:
                        myHolder.iv_downloading.setVisibility(View.GONE);
                        myHolder.iv_download_fail.setVisibility(View.GONE);
                        myHolder.iv_unread.setVisibility(View.GONE);
                        myHolder.playAnim.stop();
                        myHolder.playAnim.selectDrawable(0);
                        break;
                    case MSG_STATE_DOWNLOADING:
                        myHolder.iv_downloading.setVisibility(View.VISIBLE);
                        myHolder.iv_download_fail.setVisibility(View.GONE);
                        myHolder.iv_unread.setVisibility(View.GONE);
                        myHolder.downloadingAnim.start();
                        myHolder.playAnim.stop();
                        myHolder.playAnim.selectDrawable(0);
                        break;
                    case MSG_STATE_DOWNLOAD_FAIL:
                        myHolder.downloadingAnim.stop();
                        myHolder.iv_downloading.setVisibility(View.GONE);
                        myHolder.iv_download_fail.setVisibility(View.VISIBLE);
                        myHolder.iv_unread.setVisibility(View.GONE);
                        myHolder.playAnim.stop();
                        myHolder.playAnim.selectDrawable(0);
                        break;
                    case MSG_STATE_PLAYING:
                        myHolder.downloadingAnim.stop();
                        myHolder.iv_downloading.setVisibility(View.GONE);
                        myHolder.iv_download_fail.setVisibility(View.GONE);
                        myHolder.iv_unread.setVisibility(View.GONE);
                        playAnimation = myHolder.playAnim;
                        myHolder.playAnim.start();
                        break;
                }
                myHolder.ll_audio_msg.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (playAnimation != null) {
                            playAnimation.stop();
                            playAnimation.selectDrawable(0);
                            playAnimation = null;
                        }
                        mList.get(i).setState(MSG_STATE_READ);
                        notifyItemChanged(i);
                        playAudioMsg(mList.get(i),i);
                    }
                });
                break;
            case MSG_TYPE_PICTURE:
                break;
        }

    }

    @Override
    public int getItemCount() {
        return mList == null ? 0 : mList.size();
    }

    @Override
    public int getItemViewType(int position) {
        if (mList.get(position).getSender().equals(UserInfoBean.getInstance().getUser().getUserId())) {
            return VIEW_TYPE_SELF;
        } else {
            return VIEW_TYPE_OTHERS;
        }
    }

    public void setData(List<Message> list) {
        mList = list;
    }

    public void addDataSet(List<Message> list) {
        addDataSet(list, mList.size());
    }

    public void addDataSet(List<Message> list, int position) {
        Message currentPlayMsg = null;
        if (currentPlayPosition != RecyclerView.NO_POSITION && mList.size() > currentPlayPosition) {
            currentPlayMsg = mList.get(currentPlayPosition);
        }
        mList.addAll(position, list);
        if (currentPlayMsg != null && currentPlayPosition >= position) {
            int newPosition = currentPlayPosition + list.size();
            if (mList.get(newPosition).getMsgId() == currentPlayMsg.getMsgId()) {
                mList.get(newPosition).setState(currentPlayMsg.getState());
                currentPlayPosition = newPosition;
            }
        }
        notifyItemInserted(position);
        notifyItemRangeChanged(position, this.mList.size() - list.size());
    }

    public void addOldData(List<Message> list) {
        Message currentPlayMsg = null;
        if (currentPlayPosition != RecyclerView.NO_POSITION) {
            currentPlayMsg = mList.get(currentPlayPosition);
        }
        mList.addAll(0,list);
        if (currentPlayMsg != null) {
            int newPosition = currentPlayPosition + list.size();
            if (mList.get(newPosition).getMsgId() == currentPlayMsg.getMsgId()) {
                mList.get(newPosition).setState(currentPlayMsg.getState());
                currentPlayPosition = newPosition;
            }
        }
        notifyDataSetChanged();
    }

    private void playAudioMsg(final Message message,int position) {
        if (message.getLocalStorage() != null) {
            File file = new File(message.getLocalStorage());
            if (file.exists()) {
                boolean isCurrentPlay = currentPlayPosition == position;
                stopPlayAudio();
                mediaPlayer.reset();
                if (isCurrentPlay) {    //如果正在播放该消息
                    return;
                }
                try {
                    currentPlayPosition = position;
                    message.setState(MSG_STATE_PLAYING);
                    notifyItemChanged(position);
                    mediaPlayer.setDataSource(file.getAbsolutePath());
                    mediaPlayer.prepare();
                    mediaPlayer.start();
                    mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                        @Override
                        public void onCompletion(MediaPlayer mp) {
                            stopPlayAudio();
                        }
                    });
                } catch (IOException e) {
                    message.setLocalStorage("");
                    dbController.insertOrReplace(message);
                    stopPlayAudio();
                }
            } else {
                downLoadAudioMsg(message.getMsgContent(),position);
            }
        } else {
            downLoadAudioMsg(message.getMsgContent(),position);
        }
    }

    public void stopPlayAudio() {
        if (mediaPlayer.isPlaying()) {
            mediaPlayer.stop();
        }
        if (playAnimation != null) {
            playAnimation.stop();
            playAnimation.selectDrawable(0);
            playAnimation = null;
        }
        if (currentPlayPosition != RecyclerView.NO_POSITION) {
            if (mList.get(currentPlayPosition) != null) {
                mList.get(currentPlayPosition).setState(MSG_STATE_READ);
                notifyItemChanged(currentPlayPosition);
            }
            currentPlayPosition = RecyclerView.NO_POSITION;
        }
    }

    private void downLoadAudioMsg(final String url,final int position) {

        mList.get(position).setState(MSG_STATE_DOWNLOADING);
        notifyItemChanged(position);

        Request request = new Request.Builder().url(UrlContants.FILE_URL + "resources/watch/"+url).build();
        new OkHttpClient().newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                mList.get(position).setState(MSG_STATE_DOWNLOAD_FAIL);
                notifyItemChanged(position);
            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                new Thread() {
                    @Override
                    public void run() {
                        super.run();
                        File file = new File(Environment.getExternalStorageDirectory().getPath() + "/Android/data/com.waterworld.watch/files/"+url.split("/")[0]+"/"+url.split("/")[1]);
                        if (!file.exists()) {
                            file.mkdirs();
                        }
                        OutputStream outputStream = null;
                        InputStream inputStream = response.body().byteStream();
                        try {
                            outputStream = new FileOutputStream(Environment.getExternalStorageDirectory().getPath() + "/Android/data/com.waterworld.watch/files/"+url);
                            byte [] buff = new byte[1024];
                            int len;
                            while ((len=inputStream.read(buff)) != -1) {
                                outputStream.write(buff,0,len);
                            }
                            outputStream.flush();

                            //语音下载成功
                            android.os.Message msg = new android.os.Message();
                            msg.what = DOWNLOAD_SUCCESS;
                            Bundle bundle = new Bundle();
                            bundle.putInt("position",position);
                            bundle.putString("url",url);
                            msg.setData(bundle);
                            mHandler.sendMessage(msg);

                        } catch (Exception e){
                            e.printStackTrace();
                        }finally {
                            if(outputStream!=null){
                                try {
                                    outputStream.close();
                                } catch(IOException e) {
                                    e.printStackTrace();
                                }
                            }
                            if(inputStream!=null){
                                try {
                                    inputStream.close();
                                } catch(IOException e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    }
                }.start();
            }
        });

    }

    class MyHolder extends RecyclerView.ViewHolder{
        @BindView(R.id.tv_msg_time)
        TextView tv_msg_time;

        @BindView(R.id.tv_name)
        TextView tv_name;

        @BindView(R.id.iv_downloading)
        ImageView iv_downloading;

        @BindView(R.id.iv_download_fail)
        ImageView iv_download_fail;

        @BindView(R.id.fl_chat_msg)
        FrameLayout fl_chat_msg;

        @BindView(R.id.ll_audio_msg)
        LinearLayout ll_audio_msg;

        @BindView(R.id.tv_duration)
        TextView tv_duration;

        @BindView(R.id.iv_play_anim)
        ImageView iv_play_anim;

        @BindView(R.id.tv_text_msg)
        TextView tv_text_msg;

        @BindView(R.id.iv_unread)
        ImageView iv_unread;

        @BindView(R.id.iv_headimage)
        CircleImageView iv_headimage;

        private AnimationDrawable playAnim;
        private AnimationDrawable downloadingAnim;

        public MyHolder(@NonNull View itemView) {
            super(itemView);
            ButterKnife.bind(this,itemView);
            playAnim = (AnimationDrawable) iv_play_anim.getBackground();
            downloadingAnim = (AnimationDrawable) iv_downloading.getBackground();
        }
    }

    @SuppressLint("HandlerLeak")
    Handler mHandler = new Handler() {
        @Override
        public void handleMessage(android.os.Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case DOWNLOAD_SUCCESS:
                    mList.get(msg.getData().getInt("position")).setState(MSG_STATE_READ);
                    mList.get(msg.getData().getInt("position")).setLocalStorage(Environment.getExternalStorageDirectory().getPath() + "/Android/data/com.waterworld.watch/files/"+msg.getData().getString("url"));
                    dbController.insertOrReplace(mList.get(msg.getData().getInt("position")));
                    playAudioMsg(mList.get(msg.getData().getInt("position")),msg.getData().getInt("position"));
                    notifyItemChanged(msg.getData().getInt("position"));
                    break;
            }
        }
    };
}
